<?php

namespace app\common\service;

use app\common\model\Area;
use app\common\model\ARYPushInterface;
use app\common\model\Consulting;
use app\common\model\ConsultingForm;
use app\common\model\ConsultingQuestion;
use app\common\model\Landing;
use app\common\model\LawCaseMoney;
use app\common\model\Lawsuit;
use app\common\model\PromotionGroup;
use app\common\traits\LocationTrait;
use ip138\Ip138;
use ShidianUtil\Net\IHttpClient;
use ShidianUtil\Utils\StringUtil;
use think\facade\Config;
use think\facade\Log;

/**
 * 案如云推送服务
 * Class ARYPushService
 * @package app\common\service
 */
class ARYPushService implements \app\common\service\ARYPushInterface
{
    use LocationTrait;

    // 推送测试
    // private $channel = 'Test';
    // 咨询问题
    private $channel = 'XXM';
    // 打官司问题
    private $channel0 = 'DGS';

    private IHttpClient $httpClient;

    public function __construct(IHttpClient $httpClient)
    {
        $this->httpClient = $httpClient;
    }

    /**
     * 推送问题
     * @param $id
     * @return bool
     */
    public function pushQuestion($id): bool
    {
        $name = '提问';

        if (!is_id($id)) {
            Log::warning('案如云推送，' . $name . ' ID不正确' . $id);
            return false;
        }

        $record = ConsultingQuestion::where('id', $id)
            ->with([
                'member',
                'category',
            ])
            ->find();

        if (!$record) {
            Log::warning('案如云推送，' . $name . ' 找不到 ID =' . $id);
            return false;
        }

        // 检测该问题下的咨询，是否有已经付费的
        $paid = Consulting::where('questionId', $record->id)->where('consultingType', '1')->find();
        $paid = (bool)$paid;

        return $this->pushARYByModel($record, $this->channel, $paid, 'q', $name);
    }

    /**
     * 推送咨询表单
     * @param $id
     * @return bool
     */
    public function pushConsultingForm($id): bool
    {

        $name = '咨询表单';

        if (!is_id($id)) {
            Log::warning('案如云推送，' . $name . ' ID不正确' . $id);
            return false;
        }

        $record = ConsultingForm::where('id', $id)
            ->with([
                'member',
                'category',
            ])
            ->find();


        if (is_null($record)) {
            Log::warning('案如云推送，' . $name . ' 找不到 ID =' . $id);
            return false;
        }

        // 检测该表单下的咨询，是否有已经付费的
        $paid = Consulting::where('consultingFormId', $record->id)->where('consultingType', '1')->find();
        $paid = (bool)$paid;

        return $this->pushARYByModel($record, $this->channel, $paid, 'f', $name);
    }

    /**
     * 推送落地页
     * @param $id
     * @return bool
     */
    public function pushLanding($id, $force = false): bool
    {
        $name = '落地页';

        if (!is_id($id)) {
            Log::warning('案如云推送，' . $name . ' ID不正确' . $id);
            return false;
        }

        $record = Landing::where('id', $id)
            ->with([
                'member',
                'category',
            ])
            ->find();


        if (is_null($record)) {
            Log::warning('案如云推送，' . $name . '找不到 ID =' . $id);
            return false;
        }

        // 检测该落地页下的咨询，是否有已经付费的
        $paid = Consulting::where('landingId', $record->id)->where('landingType', $record->landingType)->where('consultingType', '1')->find();
        $paid = (bool)$paid;

        return $this->pushARYByModel($record, $this->channel, $paid, 'l', $name, $force);
    }

    /**
     * 推送落地页
     * @param $id
     * @return bool
     */
    public function pushLawsuit($id, $force = false): bool
    {

        $name = '打官司3步曲';

        if (!is_id($id)) {
            Log::warning('案如云推送，' . $name . ' ID不正确' . $id);
            return false;
        }

        $record = Lawsuit::where('id', $id)
            ->with([
                'member',
                'category',
            ])
            ->find();


        if (is_null($record)) {
            Log::warning('案如云推送，' . $name . ' 找不到 ID =' . $id);
            return false;
        }

        // 检测该落地页下的咨询，是否有已经付费的
        $paid = Consulting::where('lawsuitId', $record->id)->where('consultingType', '1')->find();
        $paid = (bool)$paid;

        return $this->pushARYByModel($record, $this->channel0, $paid, 'a', $name, $force);
    }

    /**
     * @param ARYPushInterface $model 模型
     * @param string $defaultChannel 默认channel
     * @param bool $paid 是否有付费
     * @param string $prefix ID前缀
     * @param string $name 名称
     * @return bool
     */
    private function pushARYByModel(ARYPushInterface $model, string $defaultChannel, bool $paid, string $prefix, string $name, $force = false): bool
    {
        $id = $model->id;

        if (!$force && !in_array($model->aryStatus, [$model::UNPUSH, $model::PUSH_FAILED])) {
            Log::warning('案如云推送，' . $name . '状态不正确 ID =' . $id . ' aryStatus =' . $model->aryStatus);
            return false;
        }

        $member = $model->member;
        $category = $model->category;

        $cityId = null;
        if (isset($model->cityId) && is_id($model->cityId)) {
            $cityId = $model->cityId;
        } elseif ($member && is_id($member->cityId)) {
            $cityId = $member->cityId;
        }

        $location = $this->getLocation($cityId, $member->phone);

        $provinceName = $location['provinceName'];
        $cityName = $location['cityName'];

        $businessId = $prefix . $id;

        $cate = '无';
        if ($category) {
            $cate = $category->name;
        }

        $phone = $member->phone;

        // 开发者创建的，不推送
        if(in_array($phone,  Config::get('member.developerAccount', []))){
            return true;
        }

        $ask = $this->getFullAsk($model, $paid);

        // 补充信息
        $extra = [];
        if (isset($model->detailsValid) && $model->detailsValid == 1 && isset($model->details)) {
            $extra = $model->details;
        }

        $created = $model->created;

        // 优先获取推广组的channel，然后是模型上面保存的
        $channel = '';
        if (is_id($model->promotionGroupId)) {
            $promotionGroup = PromotionGroup::where('id', $model->promotionGroupId)->find();
            if ($promotionGroup) {
                $channel = $promotionGroup->channel;
            }
        }

        if (is_blank($channel)) {
            $channel = $model->channel ?: '';
        }

        if (is_blank($channel)) {
            $channel = $defaultChannel;
        }

        $amount = '';
        if (isset($model->moneyId) && is_id($model->moneyId)) {
            $amount = LawCaseMoney::where('id', $model->moneyId)->value('name', '');
        }

        // 设为推送中
        $model->aryStatus = $model::PUSHING;
        $model->save();

        // 开始推送
        $url = 'http://crm.anruyun.com/index/index';
        $get = [
            'fun' => 'api/receiveData/'
        ];
        $headers = [];
        $post = [
            'businessId' => $businessId,
            'channel' => $channel,
            'cate' => $cate,
            'provinceName' => $provinceName,
            'cityName' => $cityName,
            'phone' => $phone,
            'ask' => $ask,
            'amount' => $amount,
            'extra' => $extra,
            'created' => $created,
            'token' => md5('xiongmaolvshi' . $phone . $channel . $businessId),
        ];

        $response = $this->httpClient->postJSONFormat($url, $get, $headers, $post);

        $result = json_decode((string)$response->getBody(), true);

        $code = $result['code'] ?? null;
        if ($code !== 1 && $code !== '1') {

            // 推送失败
            $msg = $result['msg'] ?? null;
            $model->aryStatus = Consulting::PUSH_FAILED;
            $model->aryTime = time();
            $model->aryCode = $code;
            $model->aryMsg = $msg;
            $model->save();

            Log::error('案如云推送，' . $name . '推送失败 ID =' . $id . ' code =' . $code . ' msg' . $msg);
            return false;
        }

        // 推送成功
        $model->aryStatus = Consulting::PUSHED;
        $model->aryTime = time();
        $model->aryTimes = $model->aryTimes + 1;
        $model->aryCode = $code;
        $model->aryMsg = $result['msg'] ?? null;
        $model->save();

        Log::info('案如云推送，' . $name . '推送成功 ID =' . $id);

        return true;
    }

    /**
     * 获取城市名称
     * @param $cityId
     * @param $phone
     * @return array|string[]
     */
    private function getLocation($cityId, $phone): array
    {
        if (is_id($cityId)) {
            $city = Area::where('id', $cityId)->find();

            $province = null;
            if ($city) {
                $province = Area::where('id', $city->pid)->find();
            }

            $provinceName = $province ? $province->name : '';
            $provinceName = StringUtil::replace($provinceName, ['省', '市'], '');
            $cityName = $city ? $city->name : '';
            $cityName = StringUtil::replace($cityName, ['市'], '');

            return [
                'provinceName' => $provinceName,
                'cityName' => $cityName,
            ];

        }

        if (not_blank($phone)) {

            $data = $this->getProvinceCityByPhone($phone);

            $provinceName = $data['provinceName'] ?? '';
            $cityName = $data['cityName'] ?? '';

            if (is_blank($cityName)) {
                $cityName = $provinceName;
            }

            return [
                'provinceName' => $provinceName,
                'cityName' => $cityName,
            ];
        }

        return [
            'provinceName' => '',
            'cityName' => '',
        ];
    }

    private function getIp138(): Ip138
    {
        return app(Ip138::class);
    }

    /**
     * 获取问题描述
     * @param ARYPushInterface $model
     * @param $paid
     * @return string
     */
    private function getFullAsk(ARYPushInterface $model, $paid): string
    {
        $ask = '';
        if (isset($model->ask) && not_blank($model->ask)) {
            $ask = $model->ask;
        } else {
            $category = $model->category;
            if ($category) {
                $ask = $category->name;
            }
        }

        // 可选题
        // if (isset($model->details)) {
        //     $details = $model->details;
        //     if (!empty($details)) {
        //         $details_arr = [];
        //         foreach ($details as $item) {
        //             $content = $item['content'] ?? '';
        //             $result = $item['result'] ?? null;
        //             $type = $item['type'] ?? 102;
        //             if (!is_null($result)) {
        //                 if ($type == 101) {
        //                     $option = ArrayUtil::find($item['options'], function ($option) use ($result) {
        //                         return ($option['value'] ?? null) == $result;
        //                     });
        //                     if ($option) {
        //                         $content .= ($option['content'] ?? '');
        //                     }
        //                 } else {
        //                     $content .= $result;
        //                 }
        //                 $details_arr[] = $content;
        //             }
        //         }
        //         $ask .= '；';
        //         $ask .= implode('。', $details_arr);
        //     }
        // }


        if ($paid) {
            if ($model->aryMatch == 1) {
                $pre = '【电话】';
            } else {
                $pre = '【付费】';
            }
            $ask = $pre . $ask;
        }

        return $ask;
    }
}
